
#include "SDLJeu.h"
#include "Temps.h"


#include <time.h>
#include <assert.h>
#include <stdbool.h>


/* Constantes liées aux images (tile set) utilisées >>>>> à mettre dans un fichier !!!! */
	const int HAUTEUR_TILE_SOL = 16;
	const int LARGEUR_TILE_SOL = 16;
	const int NB_TILE_PAR_LIGNE = 10;

	const int HAUTEUR_SPRITE = 30;
	const int LARGEUR_SPRITE = 30;

	const int HAUTEUR_SPRITE_ATK = 40;
	const int LARGEUR_SPRITE_ATK = 40;

	const int LARGEUR_TILE_BARRE_DU_HAUT = 10;
	const int HAUTEUR_TILE_BARRE_DU_HAUT = 20;

	/* dimension de la fenêtre : 800*820 car c'est une taille affichable sur la plupart des écrans et ça permet d'afficher une zone de 50*50 cases + barre des coeurs en haut */ /* on pourrait aussi faire du scrolling... mais c'est pas ce qu'on veux */
	const int LARGEUR_FENETRE = 800; /* = LARGEUR_TILE_SOL * 50;*/
	const int HAUTEUR_FENETRE = 820; /* = HAUTEUR_TILE_SOL * 50 + HAUTEUR_TILE_BARRE_DU_HAUT;*/
/* ************/


/* Déclaration des fonctions internes au module : */

    /* Fonction récupérée qui charge un image à partir d'un fichier BMP */
    SDL_Surface* SDL_load_image(const char* filename);

    /* Fonction récupérée qui blit une surface source sur un surface destination à la position désirée */
    void SDL_apply_surface(SDL_Surface* source, SDL_Surface* destination, int x, int y);

    /* Fonctions de chargement des images */
    void sdlChargeImagesLink(SDLJeu* p_sdl_jeu);
    void sdlChargeImagesSolsMurs(SDLJeu* p_sdl_jeu);
    void sdlChargeImagesObjets(SDLJeu* p_sdl_jeu);
    void sdlChargeImagesMonstres(SDLJeu* p_sdl_jeu);

/* Fin des déclarations */

void sdlChargeImagesLink(SDLJeu* p_sdl_jeu)
{
    int i; /* i : position de l'image sur l'axe des x */
    int direction;
    SDL_Surface* tileset;
    SDL_Rect rect_source;
    SDL_Rect rect_dest;

    /* Chargement du tile set à découper */
    tileset = SDL_load_image("data/hero.bmp");
    assert(tileset != NULL);


    rect_source.w = LARGEUR_SPRITE;
    rect_source.h = HAUTEUR_SPRITE;

    /* Pour bien centrer link sur sa case, inutile en fait tant que la surface source aura la même taille que la destination */
    rect_dest.x = 0;
    rect_dest.y = 0;

    /* Images de Link sans attaque */
    for (direction=0 ; direction<4 ; direction++) /* direction = 0 haut, 1 bas, 2 gauche, 3 droite */
    {
        for (i=0 ; i<3 ; i++)
        {
            rect_source.x = i * LARGEUR_SPRITE;
            rect_source.y = direction * HAUTEUR_SPRITE;

            p_sdl_jeu->surf_link[direction][i] = SDL_CreateRGBSurface(SDL_HWSURFACE,LARGEUR_SPRITE,HAUTEUR_SPRITE,32,0,0,0,0);
            SDL_SetColorKey(p_sdl_jeu->surf_link[direction][i], SDL_SRCCOLORKEY, SDL_MapRGB(tileset->format, 255, 0, 255));
            SDL_BlitSurface(tileset, &rect_source, p_sdl_jeu->surf_link[direction][i], &rect_dest);
        }
    }

    /* Images de Link qui attaque */
    rect_source.w = LARGEUR_SPRITE_ATK;
    rect_source.h = HAUTEUR_SPRITE_ATK;

    /* Pour bien centrer link sur sa case */
    rect_dest.x = 0;
    rect_dest.y = 0;

    for (direction=0 ; direction<4 ; direction++) /* direction = 0 haut, 1 bas, 2 gauche, 3 droite */
    {
        for (i=0 ; i<5 ; i++)
        {
            rect_source.x = i * LARGEUR_SPRITE_ATK;
            rect_source.y = direction * HAUTEUR_SPRITE_ATK + (4 * HAUTEUR_SPRITE); /* on décale la hauteur avec les images sans attaque qu'on a déjà traité */

            p_sdl_jeu->surf_link[direction][i+3] = SDL_CreateRGBSurface(SDL_HWSURFACE,LARGEUR_SPRITE,HAUTEUR_SPRITE,32,0,0,0,0);
            SDL_SetColorKey(p_sdl_jeu->surf_link[direction][i+3], SDL_SRCCOLORKEY, SDL_MapRGB(tileset->format, 255, 0, 255));
            SDL_BlitSurface(tileset, &rect_source, p_sdl_jeu->surf_link[direction][i+3], &rect_dest);
        }
    }

}


void sdlChargeImagesSolsMurs(SDLJeu* p_sdl_jeu)
{
    int i,j; /* i : position de l'image sur l'axe des x, j : position de l'image sur l'axe des y */
    SDL_Surface* tileset;
    SDL_Rect rect_source;
    SDL_Rect rect_dest;

    /* Chargement du tile set à découper */
    tileset = SDL_load_image("data/sols_murs.bmp");
    assert(tileset != NULL);


    rect_source.w = LARGEUR_TILE_SOL;
    rect_source.h = HAUTEUR_TILE_SOL;


    rect_dest.x = 0;
    rect_dest.y = 0;

    /* Images des sols */
    for (i=0 ; i<10 ; i++)
    {
        for(j=0 ; j<3 ; j++)
        {
            rect_source.x = i * LARGEUR_TILE_SOL;
            rect_source.y = j * HAUTEUR_TILE_SOL;

            p_sdl_jeu->surf_sol[i+j*NB_TILE_PAR_LIGNE] = SDL_CreateRGBSurface(SDL_HWSURFACE,LARGEUR_TILE_SOL,HAUTEUR_TILE_SOL,32,0,0,0,0);
            SDL_SetColorKey(p_sdl_jeu->surf_sol[i+j*NB_TILE_PAR_LIGNE], SDL_SRCCOLORKEY, SDL_MapRGB(tileset->format, 255, 0, 255));
            SDL_BlitSurface(tileset, &rect_source, p_sdl_jeu->surf_sol[i+j*NB_TILE_PAR_LIGNE], &rect_dest);
        }
    }

    /* Images des murs */
    for (i=0 ; i<10 ; i++)
    {
        for(j=3 ; j<9 ; j++)
        {
            rect_source.x = i * LARGEUR_TILE_SOL;
            rect_source.y = j * HAUTEUR_TILE_SOL;

            p_sdl_jeu->surf_mur[i+(j-3)*NB_TILE_PAR_LIGNE] = SDL_CreateRGBSurface(SDL_HWSURFACE,LARGEUR_TILE_SOL,HAUTEUR_TILE_SOL,32,0,0,0,0);
            SDL_SetColorKey(p_sdl_jeu->surf_mur[i+(j-3)*NB_TILE_PAR_LIGNE], SDL_SRCCOLORKEY, SDL_MapRGB(tileset->format, 255, 0, 255));
            SDL_BlitSurface(tileset, &rect_source, p_sdl_jeu->surf_mur[i+(j-3)*NB_TILE_PAR_LIGNE], &rect_dest);
        }
    }

}


void sdlChargeImagesObjets(SDLJeu* p_sdl_jeu)
{
    int i; /* i : position de l'image sur l'axe des x */
    SDL_Surface* tileset;
    SDL_Rect rect_source;
    SDL_Rect rect_dest;

	/* Coeurs pour la barre d'infos */
    /* Chargement du tile set à découper */
    tileset = SDL_load_image("data/coeurs.bmp");
    assert(tileset != NULL);


    rect_source.w = LARGEUR_TILE_BARRE_DU_HAUT;
    rect_source.h = HAUTEUR_TILE_BARRE_DU_HAUT;


    rect_dest.x = 0;
    rect_dest.y = 0;

    /* Images de Link sans attaque */
    for (i=0 ; i<2 ; i++)
    {
        rect_source.x = i * LARGEUR_TILE_BARRE_DU_HAUT;
        rect_source.y = 0;

        p_sdl_jeu->surf_coeur[i] = SDL_CreateRGBSurface(SDL_HWSURFACE,LARGEUR_TILE_BARRE_DU_HAUT,HAUTEUR_TILE_BARRE_DU_HAUT,32,0,0,0,0);
        SDL_BlitSurface(tileset, &rect_source, p_sdl_jeu->surf_coeur[i], &rect_dest);
    }


/* Objets de la zone de jeu à proprement parler */
	p_sdl_jeu->surf_objets[0] = SDL_load_image("data/coeur_terrain.bmp");
	SDL_SetColorKey(p_sdl_jeu->surf_objets[0], SDL_SRCCOLORKEY, SDL_MapRGB(p_sdl_jeu->surf_objets[0]->format, 255, 0, 255));

}

/* soldat uniquement pour l'instant */
void sdlChargeImagesMonstres(SDLJeu* p_sdl_jeu)
{
    const int LARGEUR_SOLDAT = 30;
    const int HAUTEUR_SOLDAT = 30;

    int i,j; /* i : position de l'image sur l'axe des x, j : position de l'image sur l'axe des y */
    int direction;
    SDL_Surface* tileset;
    SDL_Rect rect_source;
    SDL_Rect rect_dest;

    /* Chargement du tile set à découper */
    tileset = SDL_load_image("data/soldat.bmp");
    assert(tileset != NULL);


    rect_source.w = LARGEUR_SOLDAT;
    rect_source.h = HAUTEUR_SOLDAT;

    /* ... */
    rect_dest.x = 0;
    rect_dest.y = 0;

    /* Images du soldat */
    for (direction=0 ; direction<4 ; direction++) /* direction = 0 haut, 1 bas, 2 gauche, 3 droite */
    {
        j = direction;
        for (i=0 ; i<3 ; i++)
        {
            rect_source.x = i * LARGEUR_SOLDAT;
            rect_source.y = j * HAUTEUR_SOLDAT;

            p_sdl_jeu->surf_monstre[0][direction][i] = SDL_CreateRGBSurface(SDL_HWSURFACE,LARGEUR_SOLDAT,HAUTEUR_SOLDAT,32,0,0,0,0);
            SDL_SetColorKey(p_sdl_jeu->surf_monstre[0][direction][i], SDL_SRCCOLORKEY, SDL_MapRGB(tileset->format, 255, 0, 255));
            SDL_BlitSurface(tileset, &rect_source, p_sdl_jeu->surf_monstre[0][direction][i], &rect_dest);
        }
    }

	/* Monstre "boule" */
	p_sdl_jeu->surf_monstre_boule = SDL_load_image("data/boule2.bmp");
	SDL_SetColorKey(p_sdl_jeu->surf_monstre_boule, SDL_SRCCOLORKEY, SDL_MapRGB(p_sdl_jeu->surf_monstre_boule->format, 255, 0, 255));


}



void sdlJeuInit (SDLJeu* p_sdl_jeu)
{


	jeuInit( &(p_sdl_jeu->jeu) );

    /* Initialisation de SDL en mode video */
    if ( SDL_Init( SDL_INIT_VIDEO ) == -1)
    {
        printf( "Impossible d'initialiser SDL : %s\n", SDL_GetError() );
        exit(EXIT_FAILURE);
    }

    /* Titre de la fenêtre que l'on va créer */
	SDL_WM_SetCaption( "Zelda - Link's Devil", NULL );

    /* Icone à coté du titre */
	SDL_WM_SetIcon(SDL_LoadBMP("data/icone.bmp"), NULL); /*pas de SDL_load_image car l'image n'a pas besoin d'être optimisée et il en veux pas de toute façon...*/

    /* Initialisation de la surface écran */
    /* on utilise la mémoire video et on active le double buffering */
	p_sdl_jeu->surf_ecran = SDL_SetVideoMode(LARGEUR_FENETRE, HAUTEUR_FENETRE, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);
    /* ou bien on pourrait utiliser la mémoire centrale : p_sdl_jeu->surf_ecran = SDL_SetVideoMode(600, dimy, 32, SDL_SWSURFACE); */
	assert( p_sdl_jeu->surf_ecran != NULL);

    /* Chargement des images */
    /*pour Link *//* Chargement des images des monstres *//* Chargement des images des sols et des murs *//* Chargement des images des objets divers et des coeurs */
    sdlChargeImagesLink(p_sdl_jeu);

    sdlChargeImagesSolsMurs(p_sdl_jeu);

    sdlChargeImagesObjets(p_sdl_jeu);

    sdlChargeImagesMonstres(p_sdl_jeu);
}



void sdlJeuAff (SDLJeu *p_sdl_jeu, int num_image, bool* p_attaque_epee)
{
    int x,y;
    int i;

    Bloc bloc;
    Objet objet;
    const Zone* p_zone = carGetConstPZoneActive( jeuGetConstPCarte(&p_sdl_jeu->jeu) );
    const Link* p_link = jeuGetConstPLink(&p_sdl_jeu->jeu);
    const Monstre* tab_monstres = jeuGetConstTabMonstres(&p_sdl_jeu->jeu);

    int direction; /* utilisé pour déterminer l'orientation de l'image à afficher */
    int categorie; /* utilisé pour déterminer la bonne image du monstre à afficher */

    /* On remplit l'écran de noir */
	SDL_FillRect( p_sdl_jeu->surf_ecran, &p_sdl_jeu->surf_ecran->clip_rect, SDL_MapRGB( p_sdl_jeu->surf_ecran->format, 0, 0, 0 ) );


	p_sdl_jeu->surf_ecran_centre = SDL_CreateRGBSurface(SDL_HWSURFACE, zonGetDimension(p_zone)*LARGEUR_TILE_SOL, zonGetDimension(p_zone)*HAUTEUR_TILE_SOL+HAUTEUR_TILE_BARRE_DU_HAUT, 32,0,0,0,0);


    p_sdl_jeu->surf_barre_infos = SDL_CreateRGBSurface(SDL_HWSURFACE, zonGetDimension(p_zone)*LARGEUR_TILE_SOL, HAUTEUR_TILE_BARRE_DU_HAUT, 32,0,0,0,0);
    p_sdl_jeu->surf_zone = SDL_CreateRGBSurface(SDL_HWSURFACE, zonGetDimension(p_zone)*LARGEUR_TILE_SOL, zonGetDimension(p_zone)*HAUTEUR_TILE_SOL, 32,0,0,0,0);

/* La barre d'infos */
    /* Affichage des coeurs, pour l'instant c'est nul ! Faudra compléter quand Link sera OK avec nb coeurs max aussi */
    for (x=0 ; x<linGetNbCoeurs(p_link) ; x++)
    {
        SDL_apply_surface(p_sdl_jeu->surf_coeur[0], p_sdl_jeu->surf_barre_infos, x*LARGEUR_TILE_BARRE_DU_HAUT, 0);
    }

    SDL_apply_surface(p_sdl_jeu->surf_barre_infos, p_sdl_jeu->surf_ecran_centre, 0, 0);


/* La zone */
	/* Affichage de la zone */
    for(x=0 ; x<zonGetDimension(p_zone) ; x++)
    {
        for(y=0 ; y<zonGetDimension(p_zone) ; y++)
        {
            bloc = zonGetBlocXY(p_zone, x, y);
            objet = zonGetObjetXY(p_zone, x, y);

            /* on affiche le bloc, c'est à dire, le sol ou le mur */
            switch(bloc)
            {
                case mur :
                    SDL_apply_surface(p_sdl_jeu->surf_mur[12], p_sdl_jeu->surf_zone, x*LARGEUR_TILE_SOL, y*HAUTEUR_TILE_SOL);
                    break;
                case dalle :
                    SDL_apply_surface(p_sdl_jeu->surf_sol[0], p_sdl_jeu->surf_zone, x*LARGEUR_TILE_SOL, y*HAUTEUR_TILE_SOL);
                    break;
                case herbe :
                    SDL_apply_surface(p_sdl_jeu->surf_sol[2], p_sdl_jeu->surf_zone, x*LARGEUR_TILE_SOL, y*HAUTEUR_TILE_SOL);
                    break;
                case touffe_herbe :
                    SDL_apply_surface(p_sdl_jeu->surf_sol[4], p_sdl_jeu->surf_zone, x*LARGEUR_TILE_SOL, y*HAUTEUR_TILE_SOL);
                    break;
                case fleur1 :
                    SDL_apply_surface(p_sdl_jeu->surf_sol[3], p_sdl_jeu->surf_zone, x*LARGEUR_TILE_SOL, y*HAUTEUR_TILE_SOL);
                    break;
                case bord :
                    SDL_apply_surface(p_sdl_jeu->surf_mur[0], p_sdl_jeu->surf_zone, x*LARGEUR_TILE_SOL, y*HAUTEUR_TILE_SOL);
                    break;
                default :
                    break;
            }

            /* on affiche l'objet par dessus s'il y en a un */
            switch(objet)
            {
                case aucun :
                    break;
                case coeur :
                    SDL_apply_surface(p_sdl_jeu->surf_objets[0], p_sdl_jeu->surf_zone, x*LARGEUR_TILE_SOL, y*HAUTEUR_TILE_SOL);
                    break;
                default :
                    break;
			}
        }
    }


    /* Copie des sprites des soldats sur l'écran centré */
    for (i=0 ; i<p_sdl_jeu->jeu.nb_monstres ; i++)
    {
        if (monGetEtat(&tab_monstres[i]) != mort)
        {
            x = monGetPosX(&tab_monstres[i]) * LARGEUR_TILE_SOL;
            y = monGetPosY(&tab_monstres[i]) * HAUTEUR_TILE_SOL;
            SDL_apply_surface( p_sdl_jeu->surf_monstre_boule, p_sdl_jeu->surf_zone, x, y);
        }

/* Le problème de l'image du soldat c'est qu'elle est trop grosse par rapport à la taille des tiles des blocs don on ne s'en sert pas en fait... mais il faudrait juste changer les images à charger, ce qui suit est OK*/
/*        if (monGetEtat(&tab_monstres[i]) != mort)
        {
            x = monGetPosX(&tab_monstres[i]) * LARGEUR_TILE_SOL;
            y = monGetPosY(&tab_monstres[i]) * HAUTEUR_TILE_SOL -15;
*/
            /* Comme Direction et Categorie sont des enum, donc des int, on peut directement les affecter et les utiliser comme indices pour le tableau, si c'était pas le cas, il suffirait d'affecter le nombre souhaitée selon la categorie ou la direction */
/*            categorie = monGetConstCategorie(&tab_monstres[i]);
            direction = monGetConstDirection(&tab_monstres[i]);

            switch ( direction )
            {
                case haut :
                    SDL_apply_surface( p_sdl_jeu->surf_monstre[categorie][direction][num_image], p_sdl_jeu->surf_zone, x, y);
                    break;
                case bas :
                    SDL_apply_surface( p_sdl_jeu->surf_monstre[categorie][direction][num_image], p_sdl_jeu->surf_zone, x, y);
                    break;
                case gauche :
                    SDL_apply_surface( p_sdl_jeu->surf_monstre[categorie][direction][num_image], p_sdl_jeu->surf_zone, x, y);
                    break;
                case droite :
                    SDL_apply_surface( p_sdl_jeu->surf_monstre[categorie][direction][num_image], p_sdl_jeu->surf_zone, x, y);
                    break;
            }
        }
*/

    }

    /* Copie du sprite de link sur l'écran centré */

    direction = linGetDirection(p_link);

    if(*p_attaque_epee == true)
    {
        /* petit ajustement de la position de link pour l'affichage pour éviter d'être trop profondément dans le décor */
        x = linGetPosX(p_link) * LARGEUR_TILE_SOL-14;
        y = linGetPosY(p_link) * HAUTEUR_TILE_SOL-16;

        SDL_apply_surface(p_sdl_jeu->surf_link[direction][3], p_sdl_jeu->surf_zone, x, y);
        SDL_apply_surface(p_sdl_jeu->surf_link[direction][4], p_sdl_jeu->surf_zone, x, y);
        SDL_apply_surface(p_sdl_jeu->surf_link[direction][5], p_sdl_jeu->surf_zone, x, y);
        SDL_apply_surface(p_sdl_jeu->surf_link[direction][6], p_sdl_jeu->surf_zone, x, y);
        SDL_apply_surface(p_sdl_jeu->surf_link[direction][7], p_sdl_jeu->surf_zone, x, y);

        *p_attaque_epee = false;
    }
    else
    {
        /* petit ajustement de la position de link pour l'affichage pour éviter d'être trop profondément dans le décor */
        x = linGetPosX(p_link) * LARGEUR_TILE_SOL-7;
        y = linGetPosY(p_link) * HAUTEUR_TILE_SOL-8;

        SDL_apply_surface( p_sdl_jeu->surf_link[direction][num_image], p_sdl_jeu->surf_zone, x, y);
    }



	SDL_apply_surface(p_sdl_jeu->surf_zone, p_sdl_jeu->surf_ecran_centre, 0, HAUTEUR_TILE_BARRE_DU_HAUT);



	/* Calcul des coordonnées de centrage pour l'écran centré */
	x = LARGEUR_FENETRE/2 - (LARGEUR_TILE_SOL * zonGetDimension(p_zone) )/2; /* ...- largeur de l'écran centré /2 */
	y = HAUTEUR_FENETRE/2 - (HAUTEUR_TILE_SOL * zonGetDimension(p_zone) + HAUTEUR_TILE_BARRE_DU_HAUT )/2; /* ... - hauteur de l'écran centré /2 */

	/* Et finalement, on colle l'écran centré à ces coordonées */
	SDL_apply_surface(p_sdl_jeu->surf_ecran_centre, p_sdl_jeu->surf_ecran, x, y);
}



void sdlJeuBoucle(SDLJeu* p_sdl_jeu)
{
    bool attaque_epee; /* servira à indiquer à la fonction d'affichage s'il faut afficher link en mode marcheur ou en attaque */
    int num_image; /* servira pour indiquer l'image d'un personnage à charger, changera à chaque pas par exemple pour "animer" le personnage qui marche */
    int i = 0;
	clock_t date_derniere_attaque = 0;

	/* seed pour la génération des nombres aléatoires dont on va avoir besoin dans diverses fonctions */
	srand(time(NULL));

    SDL_Event event;
    int continue_boucle = 1;

    SDL_EnableKeyRepeat(10,10);  /* on active la répétition des touches */

    sdlJeuAff(p_sdl_jeu, num_image, &attaque_epee);
    assert( SDL_Flip( p_sdl_jeu->surf_ecran ) != -1 );

    /* tant que ce n'est pas la fin ... */
    while ( continue_boucle == 1 )
    {
    	/* On vérifie que Link n'est pas mort */
    	if (jeuLinkEstMort(&p_sdl_jeu->jeu) == true)
    	{
    		printf("************* Game Over **************\n"); /* à écrire dans la fenêtre SDL...*/
    		continue_boucle = 0;
    	}

        /* tant qu'il y a des evenements à traiter : cette boucle n'est pas bloquante */
        while ( SDL_PollEvent( &event ) )
        {
            /* Si l'utilisateur a cliqué sur la croix de fermeture, on quitte */
            if ( event.type == SDL_QUIT )
                continue_boucle = 0;

            /* Si l'utilisateur a appuyé sur une touche */
            if ( event.type == SDL_KEYDOWN )
            {
                switch ( event.key.keysym.sym )
                {
                	/* Echap/Escape pour quitter */
					case SDLK_ESCAPE :
						continue_boucle = 0;
						break;

                	/* touches d'action "mouvement" */
					case SDLK_UP :
					case SDLK_z :
						jeuActionClavier( &(p_sdl_jeu->jeu), 'h');
						num_image = num_image %2 + 1; /* on alterne les images du mouvement */
						break;

					case SDLK_DOWN :
					case SDLK_s :
						jeuActionClavier( &(p_sdl_jeu->jeu), 'b');
						num_image = num_image %2 + 1;
						break;

					case SDLK_LEFT :
					case SDLK_q :
						jeuActionClavier( &(p_sdl_jeu->jeu), 'g');
						num_image = num_image %2 + 1;
						break;

					case SDLK_RIGHT :
					case SDLK_d :
						jeuActionClavier( &(p_sdl_jeu->jeu), 'd');
						num_image = num_image %2 + 1;
						break;

					/* touches d'action "attaque" */
					case SDLK_f :
					case SDLK_g :
					case SDLK_t :
                    case SDLK_a :
					    /* affichage de l'animation d'attaque...en fait pas encore de vraie animation... */
					    attaque_epee = true;
						jeuActionClavier( &(p_sdl_jeu->jeu), 'a');
						break;

					default:
						break;
                }

            }
            else
            {
            	num_image = 0;
            }
        }

		/* Déplacement des monstres puis vérification des évènements à traiter comme les attaques des monstres, les changements de zone, les interactions avec les objets... */
		jeuDeplaceMonstres(&p_sdl_jeu->jeu);

		jeuVerifieMonstreAttaqueContact(&p_sdl_jeu->jeu, &date_derniere_attaque);

		jeuVerifieEvenements(&p_sdl_jeu->jeu);

        /* on affiche le jeu sur le buffer caché */
        sdlJeuAff(p_sdl_jeu, num_image, &attaque_epee);

        /* on permute les deux buffers (cette fonction ne doit se faire qu'une seule fois dans la boucle) */
        SDL_Flip( p_sdl_jeu->surf_ecran );

		temPatiente(100);/*SDL_Delay(100); conviendrait aussi très bien */


    }
}


void sdlJeuLibere(SDLJeu *p_sdl_jeu)
{
	int i,j,k;

	jeuLibere(&p_sdl_jeu->jeu);

	SDL_FreeSurface( p_sdl_jeu->surf_ecran );
	SDL_FreeSurface( p_sdl_jeu->surf_ecran_centre );
	SDL_FreeSurface( p_sdl_jeu->surf_barre_infos );
	SDL_FreeSurface( p_sdl_jeu->surf_zone );

	for (i=0 ; i<4 ; i++)
	{
		for (j=0 ; j<8 ; j++)
		{
			SDL_FreeSurface( p_sdl_jeu->surf_link[i][j] );
		}
	}

	for (i=0 ; i<1 ; i++) /* images d'1 seul monstre effectivement chargées */
	{
		for (j=0 ; j<4 ; j++)
		{
			for (k=0 ; k<3 ; k++)
			{
				SDL_FreeSurface( p_sdl_jeu->surf_monstre[i][j][k] );
			}
		}
	}

	SDL_FreeSurface( p_sdl_jeu->surf_monstre_boule );


	for (i=0 ; i<30 ; i++)
	{
		SDL_FreeSurface( p_sdl_jeu->surf_sol[i] );
	}
	for (i=0 ; i<60 ; i++)
	{
		SDL_FreeSurface( p_sdl_jeu->surf_mur[i] );
	}
	for (i=0 ; i<2 ; i++)
	{
		SDL_FreeSurface( p_sdl_jeu->surf_coeur[i] );
	}
	for (i=0 ; i<1 ; i++) /* image d'1 seul objet effectivement chargée */
	{
		SDL_FreeSurface( p_sdl_jeu->surf_objets[i] );
	}
}



void sdlJeuDetruit(SDLJeu *p_sdl_jeu)
{
	sdlJeuLibere(p_sdl_jeu);

    SDL_Quit();
}




SDL_Surface *SDL_load_image(const char* filename )
{
    /* Temporary storage for the image that's loaded */
    SDL_Surface* loadedImage = NULL;

    /* The optimized image that will be used */
    SDL_Surface* optimizedImage = NULL;

    /* Load the image */
    loadedImage = SDL_LoadBMP( filename );

    /* If nothing went wrong in loading the image */
    if ( loadedImage != NULL )
    {
        /* Create an optimized image */
        optimizedImage = SDL_DisplayFormat( loadedImage );

        /* Free the old image */
        SDL_FreeSurface( loadedImage );
    }

    /* Return the optimized image */
    return optimizedImage;
}


void SDL_apply_surface( SDL_Surface* source, SDL_Surface* destination, int x, int y )
{
    /* Make a temporary rectangle to hold the offsets */
    SDL_Rect offset;

    /* Give the offsets to the rectangle */
    offset.x = x;
    offset.y = y;

    /* Blit the surface */
    SDL_BlitSurface(source, NULL, destination, &offset);
}
